import styles from '@/components/form/loupeselect/styles.less';
import { getUserGroupField, getUserGroupInfo } from '@/utils/usergroup';
import { Icon, TreeSelect } from 'antd';
import classnames from 'classnames';
import DataEditCell from 'gantd/lib/data-edit-cell';
import type { Dispatch } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { connect } from 'umi';
import { renderlinkEle } from '../utils';
import SelectorModal from './SelectorModal';
import { nameKeys } from './static';
const { TreeNode } = TreeSelect;

export interface ReadElementProps {
  value: string | string[];
  showMode?: 'popover' | 'link' | 'custom' | 'simple';
  linkTo?: string | Function | object;
  customShow?: (text: string, record: any) => any;
}

export interface SelectorFormItemProps extends ReadElementProps {
  excludeId?: string;
  multiple?: boolean;
  onChange?: (selectedRowKeys: string[], selectedRows: object[]) => void;
  onCancel?: () => void;
  onOk?: (selectedRowKeys: string[], selectedRows: object[]) => void;
}

const SelectorFormItem = (props: any) => {
  const {
    listUserGroupCategoryTree,
    listUserGroupCategoryTreeByAuth,
    value,
    onChange,
    multiple,
    fetchListCategory,
    fetchListUserGroup,
    addonAfter,
    withAuth,
    showMode,
    linkTo,
    customShow,
    ...restProps
  } = props;

  const [visible, setVisible] = useState(false);
  const [forceRenderKey, setForceRenderKey] = useState(0);

  const fetch = useCallback(() => {
    if ((withAuth && listUserGroupCategoryTreeByAuth.length) || (!withAuth && listUserGroupCategoryTree.length)) return;
    fetchListCategory({ withAuth });
  }, [withAuth, listUserGroupCategoryTree, listUserGroupCategoryTreeByAuth]);

  const handlerChange = useCallback(
    (selectedRowKeys: string[], selectedRows: any) => {
      const ret: any = multiple ? selectedRowKeys : selectedRowKeys[0];
      onChange && onChange(ret);
      setVisible(false);
    },
    [multiple],
  );

  const handlerSelectorChange = useCallback((ret: any) => {
    const value = Array.isArray(ret) ? ret.map((v) => v.value) : ret && ret.value;
    onChange && onChange(value);
  }, []);
  const onCategoryReload = useCallback(() => {
    setForceRenderKey((key) => key + 1);
  }, []);

  const onLoadData = useCallback(
    (treeNode) =>
      new Promise((resolve) => {
        if (treeNode.props.children && treeNode.props.children.length) {
          resolve();
          return;
        }
        fetchListUserGroup({ id: treeNode.props.value, withAuth }).then(() => {
          resolve();
        });
      }),
    [withAuth],
  );

  const dataSource = useMemo(() => {
    return (withAuth && listUserGroupCategoryTreeByAuth) || listUserGroupCategoryTree;
  }, [withAuth, listUserGroupCategoryTree, listUserGroupCategoryTreeByAuth]);

  const renderReadElement = useCallback(() => {
    if (Array.isArray(value)) {
      return value.map((id) => getUserGroupField({ id }) || id).join('、');
    }
    if (!value) return;
    const { groupName, id } = getUserGroupInfo(value);
    switch (showMode) {
      case 'link':
        return renderlinkEle(id, groupName, linkTo);
      case 'custom':
        return customShow && customShow(id, groupName);
      default:
        return groupName;
    }
  }, [value, showMode, linkTo, customShow]);

  const loop = (data: any, renderKey: number) =>
    data.map((item: any) => {
      if (item.children && item.children.length > 0) {
        return (
          <TreeNode
            key={`${item.key}_${renderKey}`}
            value={item.value}
            title={item.title}
            isLeaf={item.isLeaf}
            selectable={item.selectable}
          >
            {loop(item.children, renderKey)}
          </TreeNode>
        );
      }
      return (
        <TreeNode
          key={`${item.key}_${renderKey}`}
          value={item.value}
          title={item.title}
          isLeaf={item.isLeaf}
          selectable={item.selectable}
        />
      );
    });

  const selectorValue = useMemo(() => {
    if (!value) return;
    if (Array.isArray(value)) {
      return value.map((id) => {
        return { label: getUserGroupField({ id }), value: id };
      });
    } else {
      return { label: getUserGroupField({ id: value }), value };
    }
  }, [value]);

  useEffect(() => {
    fetch();
  }, []);

  return (
    <DataEditCell renderText={renderReadElement} {...restProps}>
      {(editProps: any) => {
        const { onChange, onEnter, disabled, ...childProps } = editProps;
        return (
          <div className={styles.loupeSelectorWrap}>
            <div className={styles.selectWrap}>
              <TreeSelect
                value={selectorValue}
                allowClear
                labelInValue
                disabled={disabled}
                dropdownClassName={nameKeys.dropDownEleKey}
                dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                loadData={onLoadData}
                onChange={handlerSelectorChange}
                onKeyDown={onEnter}
                style={{ width: '100%' }}
                multiple={multiple}
                {...childProps}
              >
                {loop(dataSource, forceRenderKey)}
              </TreeSelect>
              <Icon
                className={disabled ? classnames(styles.searchIcon, styles.searchIconDisabled) : styles.searchIcon}
                type="search"
                onClick={() => {
                  if (disabled) return;
                  setVisible(true);
                }}
              />
            </div>
            <SelectorModal
              onCancel={() => setVisible(false)}
              multiple={multiple}
              onOk={handlerChange}
              withAuth={withAuth}
              onCategoryReload={onCategoryReload}
              visible={visible}
            />
          </div>
        );
      }}
    </DataEditCell>
  );
};

SelectorFormItem.defaultProps = {
  multiple: false,
  showMode: 'simple',
  withAuth: false,
};

export default connect(
  ({ selectors }: any) => ({
    listUserGroupCategoryTree: selectors.listUserGroupCategoryTree,
    listUserGroupCategoryTreeByAuth: selectors.listUserGroupCategoryTreeByAuth,
  }),
  (dispatch: Dispatch<any>) => ({
    fetchListCategory: (payload: any) => dispatch({ type: 'selectors/fetchListCategory', payload }),
    fetchListUserGroup: (payload: any) => dispatch({ type: 'selectors/fetchListUserGroup', payload }),
  }),
)(SelectorFormItem);
